package models.permission;

import com.google.gson.annotations.Expose;
import models.common.CodeStatus;
import org.apache.commons.lang.StringUtils;
import play.db.jpa.Model;
import utils.ShouldSkip;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 菜单结构：
 * 标题、地址、
 */
@Entity
@Table(name="tt_ADMIN_MENU")
public class Menu extends Model{
	/**
	 * 用于权限控制的名字
	 */
	@Expose
	public String name;

	/**
	 * 菜单的code
	 */
	public String code;
	/**
	 * 显示标题
	 */
	@Expose
	public String title;
	/**
	 * 访问地址
	 */
	@Expose
	public String url;
	
	/**
	 * 菜单业务排序
	 */
	@Expose
	public String orderNum;


	/**
	 * 功能点类型
	 */
	@Expose
	@Enumerated(EnumType.STRING)
	public ResourceType type;

	/**
	 * 授权，多个用逗号分隔。
	 */
	@Expose
	public String perms;


	/**
	 * 菜单图标
	 */
	@Expose
	public String icon;
	/**
	 * 上级菜单名称
	 */
	@Expose
	public String parentName;

	/**
	 * 该菜单下的子集功能，用于向角色授权功能
	 */
	@OneToMany(mappedBy="parent")
	@Expose
	public List<Menu> list;

	/**
	 * 该资源所属的上级资源，用于构建菜单结构
	 */
	@ManyToOne
	@JoinColumn(name="parent_code",referencedColumnName = "code")
	@ShouldSkip
	public Menu parent;

	@Transient
	public boolean checked;

	@Transient
	public List<Menu> menuChildren = new ArrayList<Menu>();


	public Long parentId;

	@Transient
	public boolean open ;

	@Transient
	public List<Menu> children;

	/**
	 * 0 无效
	 * 1 有效
	 */
	@Enumerated(EnumType.ORDINAL)
	public CodeStatus status;

	@PrePersist
	@PreUpdate
	public void parentSet(){
		if(this.parentId!=null) {
			this.parent = Menu.findById(parentId);
		}
	}

	@PostLoad
	public void parentIdSet(){
		this.open = true;
		this.children = this.list;
		if(this.parent==null) this.parentId = 0L;
		else this.parentId = this.parent.getId();
	}

	/**
	 * 管理员界面菜单展示时使用
	 * @param role
	 */
	public void setEmptyChildrenToNull(Role role) {
		if(StringUtils.isEmpty(this.url) && this.type== ResourceType.MENU) {
			for(Menu res : this.list) {
				if(res.type== ResourceType.MENU && role.hasResource(res.name)){
					this.menuChildren.add(res);
					res.setEmptyChildrenToNull(role); 
				}
			}
			if(this.menuChildren.size()==0)
				this.menuChildren = null; 
		}else { 
			this.menuChildren = null; 
		}
	}

	public static Menu getResourceByPerms(String perms) {
		return find("byPerms",perms).first();
	}

	/**
	 * 分配权限使用
	 * @return
	 */
	public static List<Menu> getTopLevel() {
		return find("from Menu t where t.parent is null").fetch();
	}

	/**
	 * 获取所有的顶级菜单
	 * @return
	 */
	public static List<Menu> getMenu() {
		return find("from Menu t where  t.parent is null order by orderNum").fetch();
	}

	/**
	 * 角色拥有的菜单列表,第一层
	 * @param role
	 * @return
	 */
	public static List<Menu> roleMenu(Role role) {
		if(role==null) return Collections.EMPTY_LIST; 
		
		return models.permission.Menu.find("select distinct(res) from Role role " +
				"join role.menus res " +
				" where res.parent is null  and role.code = ?1 order by res.orderNum asc", role.code).fetch();
	}
}
